/*
 * @(#)ResourceFilter .java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.framework.web; 

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.LogFactoryImpl;

import com.dcivision.framework.DebugConnection;
import com.dcivision.framework.GlobalConstant;

/**
 * Filter for close database connection.
 * If connetion is closed in this filter, that's mean there is a connection leakage
 * 
 * @author Ryan Kwan
 * @company DCIVision Limited
 * @creation date 24/06/2003
 * @version $Revision: 1.4 $
 */
public class ResourceFilter implements Filter {

  public static final String REVISION = "$Revision: 1.4 $";

  protected Log logger = new LogFactoryImpl().getInstance(this.getClass());

  private static final String PARAM_CLOSE_CONNECTION="close_connection";
  private boolean isCloseConnection=false;

  /**
   * Take this filter out of service.
   */
  public void destroy() {
	
  }

  /**
   * Select and set (if specified) the character encoding to be used to
   * interpret request parameters for this request.
   *
   * @param request The servlet request we are processing
   * @param result The servlet response we are creating
   * @param chain The filter chain we are processing
   *
   * @exception IOException if an input/output error occurs
   * @exception ServletException if a servlet error occurs
   */
  public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException, ServletException {
    try{
      chain.doFilter(request, response);
      closeConnection(request);
    }catch(Exception e){
	logger.error("Exception found from parent chain:"+e.getMessage());
	closeConnection(request);
	throw new IOException(e.getMessage());
    }
  }

  protected void closeConnection(ServletRequest request){
    Connection conn = (Connection)request.getAttribute(GlobalConstant.DB_KEY);
    logger.debug("lookup connection to close:"+((HttpServletRequest)request).getRequestURI());
    if(conn!=null){
      if(conn instanceof DebugConnection){
        logger.error("***Connection closed in filer*** Path: " + ((HttpServletRequest)request).getRequestURI() + " [Connection:" + conn +"], [" + ((DebugConnection)conn).getLastSQLQuery() + "]");
      }else{
        logger.error("***Connection closed in filer*** Path: " + ((HttpServletRequest)request).getRequestURI() + " [Connection:" + conn + "]");
      }
      try{
        conn.close();
        conn = null;
      }catch(SQLException e){
         //ignore
      }
    }
  }


  /**
   * Place this filter into service.
   * @param filterConfig The filter configuration object
   */
  public void init(FilterConfig filterConfig) throws ServletException {
    String closeConnectionStr = filterConfig.getInitParameter(PARAM_CLOSE_CONNECTION);
    isCloseConnection = closeConnectionStr !=null && "true".equals(closeConnectionStr);
    logger.info("initialize Resource Filter [Auto Close Connection:"+isCloseConnection+"]");
  }
}